/*! 
    \file    main.c
    \brief   主函数

    \version 2025-08-08, V1.1.0, 适用于 gd32c2x1 的演示
*/

#include "gd32c2x1.h"
#include "systick.h"
#include "lcd_driver.h"
#include "tft_test.h"
#include "gd32c231c_eval.h"
#include "dmx512.h"
#include "dmx512_test.h"
#include "dmx512_receiver.h"
#include "dmx512_led_controller.h"
#include "ws2812.h"
#include "ws2812_test.h"
#include "gui.h"
#include "eemul_port.h"
#include <stdio.h>
#include "bits_button.h"

/* 参数存储（EEMUL）定义：参数0=效果ID，参数1=灯带开关 */
#define PARAM_EFFECT_ID  0
#define PARAM_LED_STATE  1
static eemul_handle_t s_eemul_handle;
static const uint8_t s_descriptor[] = {
    /* PARAM_EFFECT_ID */ 1,
    /* PARAM_LED_STATE */ 1,
};

/* BitsButton按键相关变量 */
volatile uint8_t g_key_pressed = 0;//区分不同按键按下的变量

/* BitsButton按键定义 */
typedef enum
{
    USER_BUTTON_0 = 0,
    USER_BUTTON_1,
    USER_BUTTON_2,
    USER_BUTTON_3,
    USER_BUTTON_4,
    USER_BUTTON_5,
    USER_BUTTON_6,
    USER_BUTTON_7,
    USER_BUTTON_8,
    USER_BUTTON_9,
    USER_BUTTON_INVALID,
    USER_BUTTON_MAX,

    USER_BUTTON_COMBO_0 = 0x100,
    USER_BUTTON_COMBO_1,
    USER_BUTTON_COMBO_2,
    USER_BUTTON_COMBO_3,
    USER_BUTTON_COMBO_MAX,
} user_button_t;

/* BitsButton按键参数和实例 */
static const bits_btn_obj_param_t defaul_param = {
    .long_press_period_triger_ms = BITS_BTN_LONG_PRESS_PERIOD_TRIGER_MS,
    .long_press_start_time_ms = BITS_BTN_LONG_PRESS_START_TIME_MS,
    .short_press_time_ms = BITS_BTN_SHORT_TIME_MS,
    .time_window_time_ms = BITS_BTN_TIME_WINDOW_TIME_MS
};

button_obj_t btns[] = {
    BITS_BUTTON_INIT(USER_BUTTON_0, 1, &defaul_param), /* KEY_WAKEUP - 高电平有效 */
    BITS_BUTTON_INIT(USER_BUTTON_1, 0, &defaul_param), /* KEY_USER - 低电平有效 */
    // BITS_BUTTON_INIT(USER_BUTTON_2, 1, &defaul_param),
};

button_obj_combo_t btns_combo[] =
    {
        BITS_BUTTON_COMBO_INIT(
            USER_BUTTON_COMBO_0,                          // 组合键ID
            1,                                            // 有效电平
            &defaul_param,                                // 参数配置
            ((uint16_t[]){USER_BUTTON_0, USER_BUTTON_1}), // 组合按键成员
            2,                                            // 组合键成员数量
            1),                                           // 抑制单键事件
};

/* BitsButton按键状态读取函数 */
uint8_t read_key_state(struct button_obj_t *btn)
{
    uint8_t id = btn->key_id;
    // 可以让多个按钮共享GPIO读取功能
    switch(id) {
        case USER_BUTTON_0:
            return gd_eval_key_state_get(KEY_WAKEUP); // 需要自行实现
            break;
        case USER_BUTTON_1:
            return gd_eval_key_state_get(KEY_USER); 
            break;
        default:
            return 0;
            break;
    }
    return 0;
}

/* BitsButton按键结果回调函数 */
void bits_btn_result_cb(struct button_obj_t *btn, struct bits_btn_result result)
{
    printf("id:%d, event:%d, key_value:%d, long press period trigger cnt:%d \r\n",
           result.key_id, result.event, result.key_value, result.long_press_period_trigger_cnt);

    /* 处理按键事件 */
    if(result.event == BTN_STATE_PRESSED) {
        printf("id:%d pressed \n", result.key_id);
    }

    if (result.event == BTN_STATE_RELEASE)
    {
        printf("id:%d release\n", result.key_id);
    }

    if (result.event == BTN_STATE_LONG_PRESS)
    {
        if (result.key_value == 0b11)
            printf("id:%d, long press start\n", result.key_id);
        else if (result.key_value == 0b111)
        {
            printf("id:%d, long press hold, cnt:%d\n", result.key_id, result.long_press_period_trigger_cnt);
        }
        else if (result.key_value == 0b1011)
            printf("id:%d, single click and long press start\n", result.key_id);
        else if (result.key_value == 0b101011)
            printf("id:%d, double click and long press start\n", result.key_id);
    }

    if(result.event == BTN_STATE_FINISH) {
        switch(result.key_value) {
            case BITS_BTN_SINGLE_CLICK_KV:
                printf("id:%d single click\n", result.key_id);
                /* 映射到原有的按键处理 */
                if(result.key_id == USER_BUTTON_0) {
                    g_key_pressed = 1; /* WAKEUP_KEY */ 
                } else if(result.key_id == USER_BUTTON_1) {
                    g_key_pressed = 2; /* USER_KEY */
                }
                break;
            case BITS_BTN_DOUBLE_CLICK_KV:
                printf("id:%d double click", result.key_id);
                break;
            case 0b10111010:
                printf("id:%d single click and long press then single click\n", result.key_id);
                break;
            }
    }
    // 通用的长按保持处理（不同的方式判别长按保持）
    if (result.event == BTN_STATE_LONG_PRESS && result.long_press_period_trigger_cnt > 0)
    {
        printf("[%d] 长按保持 周期:%d\r\n",
               result.key_id,
               result.long_press_period_trigger_cnt);
        // 长按保持处理（如连续调节音量）
    }
}

/* DMX512和WS2812效果控制变量 */
volatile uint8_t g_effect_changed = 0;//更新显示标志位
uint8_t g_current_effect = 0;//效果编号变量
bool g_led_strip_enabled = true;  /* 灯带开关状态 */
bool g_dmx_reception_mode = false; /* DMX512接收模式标志 */

void flash_led(uint32_t times);
void display_effect_name(uint8_t effect_id); // 显示效果名称到LCD屏幕
void handle_key_press(void);                // 处理按键按下事件
void dmx512_frame_received_callback(uint16_t led_count, rgb_color_t *colors); // DMX512帧接收回调
void dmx512_error_callback(const char *error_msg); // DMX512错误回调
void display_dmx_status(void);              // 显示DMX512接收状态

/*! 
    \brief      主函数
    \param[in]  无
    \param[out] 无
    \retval     无
*/
int main(void)
{
#ifdef __FIRMWARE_VERSION_DEFINE
    uint32_t fw_ver = 0; // 固件版本号变量
#endif
    /* 配置systick定时器 */
    systick_config();
    /* 初始化调试串口 */
    gd_eval_com_init(EVAL_COM);
    /* 初始化LCD */
    lcd_init();
    
    /* 初始化BitsButton按键框架 */
    printf("\r\n   初始化BitsButton按键框架...");
    
    /* 初始化按键GPIO为输入模式（不使用EXTI中断） */
    gd_eval_key_init(KEY_USER, KEY_MODE_GPIO);
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);

    int32_t ret = bits_button_init(btns, ARRAY_SIZE(btns), btns_combo, ARRAY_SIZE(btns_combo),
                                   read_key_state, bits_btn_result_cb, printf);
    if(ret != 0) {
        printf("\r\n   BitsButton初始化失败, ret:%d", ret);
    } else {
        printf("\r\n   BitsButton按键框架初始化完成");
        printf("\r\n   支持功能: 单击、双击、长按、长按保持");
    }
    
    /* 初始化并从EEMUL(Flash)加载用户数据 */
    uint8_t saved_effect = 0;
    uint8_t saved_led_state = 0; /* 默认关灯 */
    eemul_init_config_t cfg = (eemul_init_config_t){
        .badblock_policy = EEMUL_BADBLOCK_POLICY_MARK,
        .block_mode = EEMUL_BLOCK_MODE_SUBBLOCKS,
        .bad_retry_threshold = 2,
        .enable_monotonic_sequence = true,
    };
    eemul_status_t emst = eemul_init(&s_eemul_handle, &eemul_port_ops, &cfg, s_descriptor, sizeof(s_descriptor));
    if (emst != EEMUL_STATUS_OK) {
        printf("\r\n   EEMUL初始化失败(%d)，使用默认设置", emst);
    } else {
        uint8_t tmp;
        if (eemul_read_param(&s_eemul_handle, PARAM_EFFECT_ID, &tmp) == EEMUL_STATUS_OK) {
            saved_effect = tmp;
        }
        if (eemul_read_param(&s_eemul_handle, PARAM_LED_STATE, &tmp) == EEMUL_STATUS_OK) {
            saved_led_state = tmp;
        }
        printf("\r\n   已从EEMUL加载: 效果=%d, 灯带状态=%d", saved_effect, saved_led_state);
    }
    
    /* 验证效果编号有效性，防止DMX模式编号被保存 */
    if (saved_effect >= DMX512_EFFECT_COUNT) {
        printf("\r\n   检测到无效效果编号: %d, 重置为0", saved_effect);
        g_current_effect = 0;
        /* 保存正确的效果编号到EEMUL */
        uint8_t eff0 = 0;
        uint8_t state = saved_led_state ? 1 : 0;
        if (eemul_write_param(&s_eemul_handle, PARAM_EFFECT_ID, &eff0) == EEMUL_STATUS_OK &&
            eemul_write_param(&s_eemul_handle, PARAM_LED_STATE, &state) == EEMUL_STATUS_OK) {
            printf("\r\n   已重置并保存正确的效果编号(EEMUL)");
        } else {
            printf("\r\n   保存效果编号失败(EEMUL)");
        }
    } else {
        g_current_effect = saved_effect;
    }
    
    g_led_strip_enabled = (saved_led_state != 0);
    printf("\r\n   从EEPROM加载数据: 效果=%d, 灯带状态=%d", g_current_effect, g_led_strip_enabled);
    
    /* 确保DMX接收模式标志为false */
    g_dmx_reception_mode = false;
    printf("\r\n   系统启动为本地效果模式");
    
#ifdef __FIRMWARE_VERSION_DEFINE
    fw_ver = gd32c2x1_firmware_version_get(); // 获取固件版本号
    /* 打印固件版本号 */
    printf("\r\nGD32C2X1系列固件版本: V%d.%d.%d", (uint8_t)(fw_ver >> 24), (uint8_t)(fw_ver >> 16), (uint8_t)(fw_ver >> 8));
#endif /* __FIRMWARE_VERSION_DEFINE */

    /* 打印系统、AHB、APB总线时钟频率 */
    printf("\r\nCK_SYS 时钟频率为 %d", rcu_clock_freq_get(CK_SYS));
    printf("\r\nCK_AHB 时钟频率为 %d", rcu_clock_freq_get(CK_AHB));
    printf("\r\nCK_APB 时钟频率为 %d", rcu_clock_freq_get(CK_APB));

    /* 初始化DMX512驱动，使用30个通道(10个RGB灯珠) */
    printf("\r\n   开始初始化DMX512...");
    dmx512_init(30);
    printf("\r\n   DMX512驱动初始化完成");
    
    /* 启用DMX512自动刷新，25ms间隔(40Hz) */
    dmx512_enable_auto_refresh(25);
    printf("\r\n   DMX512自动刷新已启用");
    
    /* 初始化DMX512测试模块 */
    dmx512_test_init(10, false); /* 10个LED，不自动循环 */
    printf("\r\n   DMX512测试模块初始化完成");
    
    /* 初始化WS2812驱动，使用30个LED灯珠 */
    printf("\r\n   开始初始化WS2812...");
    ws2812_init(30);
    printf("\r\n   WS2812驱动初始化完成");
    
    /* 启用WS2812自动刷新，25ms间隔(40Hz) */
    ws2812_enable_auto_refresh(25);
    printf("\r\n   WS2812自动刷新已启用");
    
    /* 初始化WS2812测试模块 */
    ws2812_test_init(30, false); /* 30个LED，不自动循环 */
    printf("\r\n   WS2812测试模块初始化完成");
    
    /* 初始化DMX512 LED控制器（但不启动） */
    dmx512_led_config_t dmx_led_config;
    dmx512_led_controller_get_default_config(&dmx_led_config);
    dmx512_led_controller_init(&dmx_led_config);
    dmx512_led_controller_set_frame_callback(dmx512_frame_received_callback);
    dmx512_led_controller_set_error_callback(dmx512_error_callback);
    dmx512_led_controller_stop();  /* 初始状态为停止，等待用户切换到DMX模式 */
    printf("\r\n   DMX512 LED控制器初始化完成（待激活）");
    
    /* 设置初始效果 */
    dmx512_test_set_effect((dmx512_effect_t)g_current_effect);
    ws2812_test_set_effect((ws2812_effect_t)g_current_effect);
    printf("\r\n   初始效果设置完成");

    /* 若启动即为关闭状态，先强制置黑，防止开机被点亮 */
    if (!g_led_strip_enabled) {
        dmx512_set_all_color(DMX512_COLOR_BLACK, 10);
        ws2812_set_all_color(WS2812_COLOR_BLACK);
        if (dmx512_is_transmission_complete()) {
            dmx512_send_frame();
        }
        if (ws2812_is_transmission_complete()) {
            ws2812_send_data();
        }
        printf("\r\n   启动时灯带为关闭，已强制置黑");
    }
    
    printf("\r\n同时控制两种灯带:");
    printf("\r\n  DMX512: 使用30个通道控制10个RGB灯珠(USART1 TX)");
    printf("\r\n  WS2812: 使用SPI+DMA控制30个RGB灯珠(PB5引脚)");
    printf("\r\n  DMX512接收: USART1 RX (PA3) - 250kbps, 8N2");
    printf("\r\n按键功能 (BitsButton框架):");
    printf("\r\n  USER_KEY: 单击=切换效果, 双击=快速切换, 长按=连续切换");
    printf("\r\n  WAKEUP_KEY: 单击=开关灯带, 双击=无功能, 长按=无功能");
    printf("\r\n  支持: 单击、双击、长按、长按保持检测");
    printf("\r\n\r\n使用说明:");
    printf("\r\n  1. 系统启动后默认为本地效果模式");
    printf("\r\n  2. 按USER_KEY循环切换11个内置效果");
    printf("\r\n  3. 在最后一个效果后再按USER_KEY进入DMX512接收模式");
    printf("\r\n  4. 在DMX接收模式下，PA3接收DMX192控台数据");
    printf("\r\n  5. 接收到的数据会同时驱动两种LED灯带");
    printf("\r\n  6. 在DMX模式下按USER_KEY可返回本地效果模式");
    
    /* 显示初始效果名称 */
    display_effect_name(g_current_effect);

    
    /* 强制触发一次效果更新 */
    g_effect_changed = 1;
    
    /* 立即执行初始静态效果（仅在灯带开启且非DMX模式时） */
    if (g_led_strip_enabled && !g_dmx_reception_mode && (g_current_effect < DMX512_EFFECT_RAINBOW)) {
        dmx512_test_run();
        ws2812_test_run();
        /* 确保数据发送 */
        if (dmx512_is_transmission_complete()) {
            dmx512_send_frame();
        }
        if (ws2812_is_transmission_complete()) {
            ws2812_send_data();
        }
    }

    printf("\r\n   进入主循环，等待按键...");
    while(1) {
        /* 检查按键按下 */
        if (g_key_pressed) {
            handle_key_press();
            g_key_pressed = 0;
        }
        
        /* 如果效果改变，更新显示 */
        if (g_effect_changed) {
            if (g_dmx_reception_mode) {
                display_dmx_status();
            } else {
                display_effect_name(g_current_effect);
                dmx512_test_set_effect((dmx512_effect_t)g_current_effect);
                ws2812_test_set_effect((ws2812_effect_t)g_current_effect);
            }
            g_effect_changed = 0;
        }
        
        /* DMX512接收模式处理 */
        if (g_dmx_reception_mode) {
            /* 检查是否有新的DMX512帧准备就绪 */
            if (dmx512_rx_is_frame_ready()) {
                /* 打印帧接收完成信息 */
                printf("\r\n[DEBUG] 帧接收完成，通道数: %d", g_dmx512_rx.channel_count);
                
                /* 获取并打印完整DMX512数据 */
                uint8_t dmx_buffer[513];
                uint16_t dmx_length = dmx512_rx_copy_data(dmx_buffer, sizeof(dmx_buffer));
                
                if (dmx_length > 0) {
                    printf("\r\n[DEBUG] 完整DMX512数据 (%d字节): \r\n", dmx_length);
                    for (int i = 0; i < dmx_length; i++) {
                        printf("%02X ", dmx_buffer[i]);
                        /* 每16个字节换行，便于阅读 */
                        if ((i + 1) % 16 == 0) {
                            printf("\r\n");
                        }
                    }
                    if (dmx_length % 16 != 0) { /* 最后一行不足16字节，补换行 */
                        printf("\r\n");
                    }
                    
                    /* 验证起始码 */
                    if (dmx_buffer[0] == 0x00) {
                        printf("[DEBUG] 起始码验证通过: 0x%02X\r\n", dmx_buffer[0]);
                    } else {
                        printf("[DEBUG] 无效起始码: 0x%02X (期望0x00)\r\n", dmx_buffer[0]);
                    }
                }
                
                /* 标记帧已处理，避免重复处理 */
                dmx512_rx_frame_processed();
            }
            
            /* 处理接收到的DMX512帧（无论灯带是否开启都要处理） */
            dmx512_led_controller_process_frame();
            
            /* 每5秒输出一次接收状态 */
            static uint32_t last_status_time = 0;
            static uint32_t status_counter = 0;
            status_counter++;
            if (status_counter >= 100) {  /* 50ms * 100 = 5秒 */
                dmx512_rx_stats_t rx_stats;
                dmx512_rx_get_stats(&rx_stats);
                printf("\r\nDMX512状态: 接收帧=%u, 有效帧=%u, 错误帧=%u", 
                       rx_stats.frames_received, rx_stats.frames_valid, rx_stats.frames_error);
                if (rx_stats.frames_received == 0) {
                    printf(" [无信号 - 检查PA3连接和DMX192控台输出]");
                }
                status_counter = 0;
            }
        }
        /* 本地效果模式 - 只在灯带开启且非DMX接收模式时运行效果 */
        else if (g_led_strip_enabled && !g_dmx_reception_mode) {
            /* 所有效果都持续刷新，简化逻辑 */
            dmx512_test_run();
            ws2812_test_run();
        }
        
        /* 处理WS2812自动刷新 */
        ws2812_auto_refresh_handler();
        
        /* 发送DMX512数据（当未启用自动刷新时） */
        if (!g_dmx512.auto_refresh && dmx512_is_transmission_complete()) {
            dmx512_send_frame();
        }
        
        /* 发送WS2812数据（当未启用自动刷新时） */
        if (!g_ws2812.auto_refresh && ws2812_is_transmission_complete()) {
            ws2812_send_data();
        }
        
        /* 延时50ms */
        delay_1ms(50);
    }
}


/*! 
    \brief      LED闪烁
    \param[in]  times: LED闪烁次数
    \param[out] 无
    \retval     无
*/
void flash_led(uint32_t times)
{
    int i;

    for(i = 0; i < times; i ++) {
        /* 点亮LED1 */
        gd_eval_led_on(LED1);
        
        /* 减少延时到50毫秒 */
        delay_1ms(50);

        /* 关闭LED1 */
        gd_eval_led_off(LED1);
        
        /* 闪烁间隔延时50毫秒 */
        if (i < times - 1) {  /* 最后一次闪烁后不需要延时 */
            delay_1ms(50);
        }
    }
}

/*!
    \brief      显示效果名称到LCD屏幕
    \param[in]  effect_id: 效果ID
    \param[out] none
    \retval     none
*/
void display_effect_name(uint8_t effect_id)
{
    static uint8_t last_effect_id = 0xFF;  /* 记录上次显示的效果ID */
    static uint8_t last_strip_status = 0xFF;  /* 记录上次的灯带状态 */
    static uint8_t initialized = 0;  /* 记录是否已初始化显示 */
    const char* effect_name;
    uint8_t current_strip_status = g_led_strip_enabled ? 1 : 0;
    
    /* 只有在效果改变或灯带状态改变时才需要更新显示 */
    if (last_effect_id == effect_id && last_strip_status == current_strip_status && initialized) {
        return;  /* 没有变化，直接返回 */
    }
    
    /* 首次显示时，显示所有内容 */
    if (!initialized) {
        /* 清屏为黑色背景 */
        lcd_clear(BLACK);
        
        /* 显示固定内容 */
        gui_draw_font_gbk24(10, 10, WHITE, BLACK, (char *)"Effect:");
        gui_draw_font_gbk24(10, 70, WHITE, BLACK, (char *)"Key Functions:");
        gui_draw_font_gbk24(10, 90, WHITE, BLACK, (char *)"USER_KEY: Switch Effect");
        gui_draw_font_gbk24(10, 110, WHITE, BLACK, (char *)"WAKEUP_KEY: On/Off Strip");
        
        initialized = 1;
    }
    
    /* 更新效果名称（第二行） */
    if (last_effect_id != effect_id) {
        /* 清除效果名称显示区域 */
        lcd_clear_region(10, 30, 230, 50, BLACK);
        
        /* 获取并显示新的效果名称 */
        effect_name = dmx512_test_get_effect_name((dmx512_effect_t)effect_id);
        gui_draw_font_gbk24(10, 30, YELLOW, BLACK, (char *)effect_name);
        
        last_effect_id = effect_id;
    }
    
    /* 更新灯带状态（第六行） */
    if (last_strip_status != current_strip_status) {
        /* 清除状态显示区域 */
        lcd_clear_region(10, 130, 210, 160, BLACK);
        
        /* 显示新的灯带状态 */
        if (g_led_strip_enabled) {
            gui_draw_font_gbk24(10, 130, GREEN, BLACK, (char *)"Strip: ON");
        } else {
            gui_draw_font_gbk24(10, 130, RED, BLACK, (char *)"Strip: OFF");
        }
        
        last_strip_status = current_strip_status;
    }
}

/*!
    \brief      处理按键按下事件
    \param[in]  none
    \param[out] none
    \retval     none
*/
void handle_key_press(void)
{
    if (g_key_pressed == 2) {
        /* USER_KEY: 切换效果或DMX接收模式 */
        if (!g_dmx_reception_mode) {
            /* 本地效果模式：切换效果 */
            g_current_effect++;
            if (g_current_effect >= DMX512_EFFECT_COUNT) {
                /* 切换到DMX接收模式 */
                g_dmx_reception_mode = true;
                dmx512_led_controller_start();
                printf("\r\nUSER_KEY: 切换到DMX512接收模式");
            } else {
                    if (g_led_strip_enabled) {
                        printf("\r\nUSER_KEY: 切换到效果 %d - %s (两种灯带同步)", g_current_effect, 
                               dmx512_test_get_effect_name((dmx512_effect_t)g_current_effect));
                    } else {
                        printf("\r\nUSER_KEY: 效果已切换到 %d - %s (灯带关闭中)", g_current_effect, 
                               dmx512_test_get_effect_name((dmx512_effect_t)g_current_effect));
                    }
            }
        } else {
            /* DMX接收模式：切换回本地效果模式 */
            g_dmx_reception_mode = false;
            g_current_effect = 0;
            dmx512_led_controller_stop();
            printf("\r\nUSER_KEY: 切换回本地效果模式");
        }
        
        g_effect_changed = 1;
        
        /* 只有在本地效果模式下才保存到EEMUL，DMX模式不保存 */
        if (!g_dmx_reception_mode) {
            uint8_t eff = g_current_effect;
            uint8_t state = g_led_strip_enabled ? 1 : 0;
            if (eemul_write_param(&s_eemul_handle, PARAM_EFFECT_ID, &eff) == EEMUL_STATUS_OK &&
                eemul_write_param(&s_eemul_handle, PARAM_LED_STATE, &state) == EEMUL_STATUS_OK) {
                printf("\r\n   数据已保存到EEMUL");
            } else {
                printf("\r\n   保存到EEMUL失败");
            }
        } else {
            printf("\r\n   DMX模式不保存到EEMUL");
        }
        
        /* 闪烁LED1一次表示USER_KEY被按下 */
        flash_led(1);

        } else if (g_key_pressed == 1) {
        /* WAKEUP_KEY: 开关灯带 */
        g_led_strip_enabled = !g_led_strip_enabled;
        
        /* 保存灯带状态到EEMUL */
        {
            uint8_t eff = g_current_effect;
            uint8_t state = g_led_strip_enabled ? 1 : 0;
            if (eemul_write_param(&s_eemul_handle, PARAM_EFFECT_ID, &eff) == EEMUL_STATUS_OK &&
                eemul_write_param(&s_eemul_handle, PARAM_LED_STATE, &state) == EEMUL_STATUS_OK) {
                printf("\r\n   数据已保存到EEMUL");
            } else {
                printf("\r\n   保存到EEMUL失败");
            }
        }
        
        if (g_led_strip_enabled) {
            printf("\r\nWAKEUP_KEY: 两种灯带已开启");
            g_effect_changed = 1;  /* 重新显示当前效果 */
        } else {
            printf("\r\nWAKEUP_KEY: 两种灯带已关闭");
            /* 关闭所有LED */
            dmx512_set_all_color(DMX512_COLOR_BLACK, 10);
            ws2812_set_all_color(WS2812_COLOR_BLACK);
            /* 立即发送数据确保LED熄灭 */
            if (dmx512_is_transmission_complete()) {
                dmx512_send_frame();
            }
            if (ws2812_is_transmission_complete()) {
                ws2812_send_data();
            }
            /* 立即更新LCD显示状态 */
            display_effect_name(g_current_effect);
        }
        
        printf("\r\n   数据已保存到EEPROM");
        /* 闪烁LED1两次表示WAKEUP_KEY被按下 - 作为最后的视觉反馈 */
        flash_led(2);
    }
}

/*!
    \brief      DMX512帧接收回调函数
    \param[in]  led_count: LED数量
    \param[in]  colors: LED颜色数组
    \param[out] none
    \retval     none
*/
void dmx512_frame_received_callback(uint16_t led_count, rgb_color_t *colors)
{
    static uint32_t frame_count = 0;
    frame_count++;
    
    /* 每100帧打印一次统计信息 */
    if (frame_count % 100 == 0) {
        dmx512_led_stats_t stats;
        dmx512_led_controller_get_stats(&stats);
        printf("\r\nDMX512接收: 帧数=%u, 更新=%u, 频率=%dHz, LED数=%d", 
               stats.frames_processed, stats.frames_updated, stats.update_rate, led_count);
    }
}

/*!
    \brief      DMX512错误回调函数
    \param[in]  error_msg: 错误消息
    \param[out] none
    \retval     none
*/
void dmx512_error_callback(const char *error_msg)
{
    printf("\r\nDMX512错误: %s", error_msg);
}

/*!
    \brief      显示DMX512接收状态
    \param[in]  none
    \param[out] none
    \retval     none
*/
void display_dmx_status(void)
{
    static uint8_t initialized = 0;
    
    /* 首次显示时，显示所有内容 */
    if (!initialized) {
        /* 清屏为黑色背景 */
        lcd_clear(BLACK);
        
        /* 显示固定内容 */
        gui_draw_font_gbk24(10, 10, WHITE, BLACK, (char *)"DMX512 Reception Mode");
        gui_draw_font_gbk24(10, 30, WHITE, BLACK, (char *)"Waiting for DMX data...");
        gui_draw_font_gbk24(10, 70, WHITE, BLACK, (char *)"Key Functions:");
        gui_draw_font_gbk24(10, 90, WHITE, BLACK, (char *)"USER_KEY: Back to Effects");
        gui_draw_font_gbk24(10, 110, WHITE, BLACK, (char *)"WAKEUP_KEY: On/Off Strip");
        
        initialized = 1;
    }
    
    /* 更新接收状态 */
    dmx512_rx_stats_t rx_stats;
    dmx512_rx_get_stats(&rx_stats);
    
    dmx512_led_stats_t led_stats;
    dmx512_led_controller_get_stats(&led_stats);
    
    /* 清除状态显示区域 */
    lcd_clear_region(10, 50, 210, 70, BLACK);
    
    char status_str[50];
    if (rx_stats.frames_received > 0) {
        snprintf(status_str, sizeof(status_str), "Frames: %u, Rate: %dHz", 
                rx_stats.frames_received, led_stats.update_rate);
        gui_draw_font_gbk24(10, 50, GREEN, BLACK, status_str);
    } else {
        gui_draw_font_gbk24(10, 50, YELLOW, BLACK, (char *)"No DMX signal detected");
    }
    
    /* 显示灯带状态 */
    lcd_clear_region(10, 130, 210, 160, BLACK);
    if (g_led_strip_enabled) {
        gui_draw_font_gbk24(10, 130, GREEN, BLACK, (char *)"Strip: ON");
    } else {
        gui_draw_font_gbk24(10, 130, RED, BLACK, (char *)"Strip: OFF");
    }
}